package org.gordonframework.core.net {
	import org.gordonframework.core.events.GProcessEvent;
	import org.gordonframework.core.process.GProcess;
	
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;	

	/**
	 * @author sampet
	 */
	public class GDisplayLoader extends Sprite implements GProcess {

		private var _loader:Loader;
		private var _request:URLRequest;
		private var _context:LoaderContext;
		private var _progress:Number = 0;
		private var _running:Boolean = false;
		private var _complete:Boolean = false;

		/**
		 * 
		 * @param request URLRequest specifying the URL of the SWF, JPEG, GIF or PNG. 
		 * @param context 
		 */
		public function GDisplayLoader(request:URLRequest = null, context:LoaderContext = null) {
			_loader = new Loader( );
			_loader.contentLoaderInfo.addEventListener( Event.COMPLETE, loaderCompleteHandler );
			_loader.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS, loaderProgressHandler );
			_loader.contentLoaderInfo.addEventListener( HTTPStatusEvent.HTTP_STATUS, dispatchEvent );
			_loader.contentLoaderInfo.addEventListener( Event.INIT, dispatchEvent );
			_loader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, dispatchEvent );
			_loader.contentLoaderInfo.addEventListener( Event.OPEN, dispatchEvent );
           	
			_request = request;			_context = context;
		}

		/**
		 * The current progression of the loader.
		 */
		public function get progress():Number {
			return _progress;
		}

		/**
		 * Indicates whether or not the loader is running.
		 */
		public function get running():Boolean {
			return _running;
		}

		/**
		 * Indicates whether or not the loader is complete.
		 */
		public function get complete():Boolean {
			return _complete;
		}

		/**
		 * Returns the loaded display.  
		 */
		public function get display():DisplayObject {
			return _loader.content;
		}

		/**
		 * 
		 */
		public function get request():URLRequest {
			return _request;
		}

		public function set request(value:URLRequest):void {
			_request = value;
		}

		/**
		 * 
		 */
		public function get context():LoaderContext {
			return _context;
		}

		public function set context(value:LoaderContext):void {
			_context = value;
		}

		/**
		 * Starts the loader.
		 */
		public function start():void {
			_progress = 0;
			_running = true;
			_complete = false;
			
			_loader.load( _request, _context );
			
			dispatchEvent( new GProcessEvent( GProcessEvent.START ) );
		}

		/**
		 * Stops the loader if its runnning.
		 */
		public function stop():void {
			if(_running) {
				_progress = 0;
				_running = false;
				_complete = false;		
				_loader.close( );
				dispatchEvent( new GProcessEvent( GProcessEvent.STOP ) );
			}
		}

		protected function loaderProgressHandler(event:ProgressEvent):void {
			_progress = event.bytesLoaded / event.bytesTotal;
			dispatchEvent( new GProcessEvent( GProcessEvent.PROGRESS, false, false, _progress ) );
		}

		protected function loaderCompleteHandler(event:Event):void {
			_progress = 1;
			_running = false;
			_complete = true;
							
			dispatchEvent( new GProcessEvent( GProcessEvent.COMPLETE, false, false, 1 ) );
		}

		override public function dispatchEvent(event:Event):Boolean {
			if(hasEventListener( event.type )) {
				return super.dispatchEvent( event );
			}
			return false;
		}
	}
}
